import {
  useAppDataDoneModel,
  useDictionariesModel,
  useSubscriptionsModel,
} from '@/models/useGlobalModel';
import { useUserModel } from '@/models/useUserModel';
import { useEffect } from 'react';
import { useRecoilState, useResetRecoilState, useSetRecoilState } from 'recoil';
import {
  getCurrentInstance,
  checkSession,
  getEnv,
  login,
  getUpdateManager,
  nextTick,
  useDidHide,
  useDidShow,
  showModal,
} from '@tarojs/taro';
import {
  setFromUid,
  removeFromUid,
  setId,
  removeId,
  setScene,
  setOpenId,
  getOpenId,
  setWxCode,
  getWxCode,
  getToken,
  setToken,
} from '@/utils/storage';
import { miniprogramStart } from './services/public/miniprogram';
import global from '@/utils/globalUtils';
import { h5Login } from '@/services/public/h5';
// import { authIsLogin } from '@/services/public/user';
import { isWechat } from '@/utils/wechat';
import { dialog, eventsBus, navigateTo } from '@vh-mobile/pro-utils';
import { parse } from 'query-string';
import { authEnvLogin, authIsLogin } from './services/public/user';
import { publicDictionary } from './services/public/public';
import dayjs from 'dayjs';
import { getSetting } from '@tarojs/taro-h5';
require('dayjs/locale/zh-cn');
dayjs.locale('zh-cn'); // use loaded locale globally

export declare type GlobalEventsType = {
  /**
   * 全局事件类型 resetUserModel:重置用户状态
   *
   */
  type: 'resetUserModel';
  /**
   * 需要传递的值
   */
  value?: any;
  /**
   * 操作成功后的回调
   */
  callback?: () => void;
};

/* 扫码进入的参数转换成对象
 * @param data
 */
const sceneToObject = (scene: any) => {
  const scenes = {};
  if (scene) {
    scene.split(',').forEach((item) => {
      const arr = item.split(':');
      scenes[arr[0]] = arr[1];
    });
  }
  return scenes;
};

/**
 * 应用有新版本
 */
const updateApp = () => {
  if (getEnv() === 'WEAPP') {
    const updateManager: any = getUpdateManager();
    updateManager.onCheckForUpdate(async (res: any) => {
      if (res.hasUpdate) {
      }
    });
    updateManager.onUpdateReady(() => {
      showModal({
        title: '更新提示',
        content: '新版本已经准备好，立即重启应用？',
        confirmText: '我知道了',
        showCancel: false,
      }).then(function (mRes: any): void {
        if (mRes.confirm) {
          updateManager.applyUpdate();
        }
      });
    });
    updateManager.onUpdateFailed(() => {
      showModal({
        title: '更新失败',
        content: '请删除小程序后重新打开',
        confirmText: '我知道了',
        showCancel: false,
      }).then(function (): void {});
    });
  }
};

/**
 * 微信登陆
 */
export const wxLogin = async () => {
  const loginRes: any = await login();

  if (loginRes.errMsg === 'login:ok') {
    try {
      const data = await miniprogramStart(
        {
          code: loginRes.code,
        },
        {
          showLoading: false,
        },
      );
      setWxCode(loginRes.code);
      setOpenId(data.data.openid);
      return data;
    } catch (e) {
      //TODO handle the exception
      throw new Error('登录失败');
    }
  } else {
    throw new Error('登录失败');
  }
};

/**
 * 处理业务参数
 */
const storageBusinessData = (option: any) => {
  if (getEnv() === 'WEAPP') {
    /**
     * 进入参数规定
     * fd:传播人
     * id:主业务id
     */
    const { params = {} }: any = option;
    // 进入业务场景值
    const gscene = option.scene;
    // 进入的参数
    const { fd, id, scene } = params;

    // 进入程序删除本地记录值
    removeFromUid();
    removeId();

    // 如果是扫码进入取参数
    const scenes = sceneToObject(scene);
    // 存入全局传播人 关系可以本地打开全局使用
    setFromUid(fd, scenes);
    // 存入全局业务id
    setId(id, scenes);
    // 存入进入场景值
    setScene(gscene);
  }
};

/**
 * 验证openid是否存在
 */
export const checkOpenId = async () => {
  if (getEnv() === 'WEAPP') {
    if (!getOpenId()) {
      await wxLogin();
    }
  }
};
/**
 * 验证wxcode是否过期
 */
const wxCheckSession = () => {
  if (getEnv() === 'WEAPP' && getWxCode()) {
    checkSession({
      success: function (res: any) {
        console.log('处于登录态', res);
      },
      fail: function (res) {
        console.log('需要重新登录', res);
        wxLogin();
      },
    });
  }
};

function Global(props: any) {
  const [appDataDoneModel, setAppDataDoneModel] = useRecoilState(useAppDataDoneModel);
  const [dictionariesModel, setDictionariesModel] = useRecoilState(useDictionariesModel);
  const [userModel, setUserModel] = useRecoilState(useUserModel);
  const resetUserModel = useResetRecoilState(useUserModel);
  // const setUseSubscriptionsModel = useSetRecoilState(useSubscriptionsModel);

  // const router = useRouter();

  const getConfigFn = (pUser: any = null, callback: any = null) => {
    // 获取公用配置
    const pDictionaries = new Promise((resolve) => {
      if (!dictionariesModel) {
        setDictionariesModel({});
        resolve(true);
        // publicDictionary()
        //   .then((res: any) => {
        //     setDictionariesModel(res.data);
        //     resolve(true);
        //   })
        //   .catch(() => {
        //     resolve(true);
        //   });
      } else {
        resolve(true);
      }
    });
    const promiseAll: any[] = [pDictionaries];
    if (pUser) {
      promiseAll.unshift(pUser);
    }
    // 加载必须的数据后页面loading取消展示页面 MainContainerCustom 中有监听这个状态控制页面
    Promise.all(promiseAll)
      .then(() => {
        setAppDataDoneModel(true);
        if (callback) {
          callback();
        }
      })
      .catch((err: any) => {
        global.log(err, appDataDoneModel);
      });
  };

  const wehcatH5 = () => {
    // 如果没有没有登录token
    const query = parse(window.location.search);

    if (query && query.code && query.state === 'STATE') {
      //换取code去后台接口登陆
      h5Login({
        code: query.code,
      })
        .then((res) => {
          setToken(res.data.token);
          setUserModel(res.data.user);
          getConfigFn();

          // location.href = window.location.origin + '/#' + location.href.split('#')[1];
        })
        .catch((e) => {
          console.log(e);
        });
    } else {
      //否则去微信授权
      const appUrl = encodeURIComponent(window.location.href.split('#')[0]);
      const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${appUrl}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`;
      window.location.href = authUrl;

      return;
    }
  };

  useEffect(() => {
    // 全局进入验证逻辑
    // 如果是微信H5
    // if (getEnv() === 'WEB') {
    //   if (!getToken() && isWechat()) {
    //     wehcatH5();
    //   } else {
    //     // 本地调试使用
    //     if (!getToken()) {
    //       if (BUILD_ENV !== 'pro') {
    //         // 如果有登录 获取用户信息
    //         authEnvLogin()
    //           .then((res: any) => {
    //             if (!res.data.token) {
    //               wehcatH5();
    //             } else {
    //               setToken(res.data.token);
    //               setUserModel(res.data.user);
    //               getConfigFn();
    //             }
    //           })
    //           .catch(() => {});
    //       } else {
    //         wehcatH5();
    //       }
    //     } else {
    //       // 如果有登录 获取用户信息
    //       const pUser = new Promise((resolve) => {
    //         if (!userModel && getToken()) {
    //           authIsLogin()
    //             .then((res: any) => {
    //               setUserModel(res.data);
    //               resolve(true);
    //             })
    //             .catch(() => {
    //               resolve(true);
    //             });
    //         } else {
    //           resolve(true);
    //         }
    //       });
    //       getConfigFn(pUser);
    //     }
    //   }
    // } else {
    //   // 其它
    // }
    // 全局进入验证逻辑

    // 如果有登录 获取用户信息  这个是demo使用 如果不是demo删除
    const pUser = new Promise((resolve) => {
      if (!userModel && getToken()) {
        setUserModel({ id: 1 });
        resolve(true);
        // authIsLogin()
        //   .then((res: any) => {
        //     setUserModel(res.data);
        //     resolve(true);
        //   })
        //   .catch(() => {
        //     resolve(true);
        //   });
      } else {
        resolve(true);
      }
    });

    getConfigFn(pUser);
    // 如果有登录 获取用户信息  这个是demo使用 如果不是demo删除

    // 全局监听事件
    eventsBus.$on('GlobalEvents', (data: GlobalEventsType) => {
      // const { type, value, callback } = data;
      const { type } = data;

      // 清空用户状态
      if (type === 'resetUserModel') {
        resetUserModel();
      }

      console.log('GlobalEvents', data);
    });
    return () => {
      eventsBus.$off('GlobalEvents');
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  //此代码为 结合 MainContainerCustom 组件来进行页面登录状态验证，需要验证的页面才会执行 和上方2选1
  // useEffect(() => {
  //   // 全局监听事件
  //   eventsBus.$on('GlobalEvents', (data: GlobalEventsType) => {
  //     const { type, value, callback } = data;
  //     // 清空用户状态
  //     if (type === 'resetUserModel') {
  //       resetUserModel();
  //     } else if (type === 'login') {
  //       // 全局登录成功就监听
  //       const pUser = new Promise((resolve) => {
  //         setUserModel(value);
  //         setToken(value.lastToken);
  //         resolve(true);
  //       });

  //       getConfigFn(pUser, callback);
  //     } else if (type === 'checkLogin') {
  //       // 如果用户存在或者appDataDoneModel应用加载完成 不需要验证
  //       if (userModel || appDataDoneModel) {
  //         return;
  //       }
  //       if (getToken()) {
  //         // 如果有登录 获取用户信息
  //         const pUser = new Promise((resolve, reject) => {
  //           authIsLogin()
  //             .then((res: any) => {
  //               setUserModel(res.data);
  //               resolve(true);
  //             })
  //             .catch(() => {
  //               reject(false);
  //             });
  //         });

  //         getConfigFn(pUser);
  //       } else {
  //         //如果需要登录并且钉钉打开
  //         if (isWechat()) {
  //           wehcatH5();
  //         }

  //         //如果是网站上打开 并且需要登录 并且是本地环境
  //         if (BUILD_ENV === 'local' && !isWechat()) {
  //           dialog.alert('提示', '检测到当前为开发模式', {
  //             confirmButtonText: '前往模拟登录',
  //             onConfirm: () => {
  //               navigateTo({
  //                 url: `/pages/devtool/index`,
  //               });
  //             },
  //           });
  //         }
  //       }
  //     }
  //     console.log('GlobalEvents', data);
  //   });
  //   return () => {
  //     eventsBus.$off('GlobalEvents');
  //   };
  //
  // }, [appDataDoneModel,userModel]);

  // 可以使用所有的 React Hooks

  useEffect(() => {
    global.log('app launch', process.env.NODE_ENV);

    storageBusinessData(getCurrentInstance().router);
    checkOpenId();

    // loadFontFace({
    //   global: true,
    //   family: 'Light',
    //   source: 'url("https://zh-market.oss-cn-shenzhen.aliyuncs.com/SourceHanSans-Light.woff")',
    // });

    // 微信小程序检查是否打开订阅
    // getSetting({
    //   withSubscriptions: true,
    // })
    //   .then((res: any) => {
    //     setUseSubscriptionsModel(res.subscriptionsSetting);
    //   })
    //   .catch(() => {});

    return function () {
      // 这个暂时不确定会不会触发
      global.log('app unlaunch');
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // 对应 onShow
  useDidShow(() => {
    wxCheckSession();
    nextTick(() => {
      updateApp();
    });
  });

  // 对应 onHide
  useDidHide(() => {
    global.log('app hide');
  });

  //为什么公用显示不放在这里，目前测试微信小程序中这里的node无法渲染的页面
  return null;
}

export default Global;
